package cn.windy.samary.module.admin.service.impl;

import cn.windy.samary.module.abstracts.service.impl.AbstractServiceImpl;
import cn.windy.samary.module.admin.common.Tree;
import cn.windy.samary.module.admin.common.UserVo;
import cn.windy.samary.module.admin.entity.*;
import cn.windy.samary.module.Constants;
import cn.windy.samary.module.admin.mapper.DeptMapper;
import cn.windy.samary.module.admin.mapper.UserMapper;
import cn.windy.samary.module.admin.mapper.UserRoleMapper;
import cn.windy.samary.module.admin.service.IDeptService;
import cn.windy.samary.module.admin.service.IUserRoleService;
import cn.windy.samary.module.admin.service.IUserService;
import cn.windy.samary.module.shiro.realm.CustomShiroRealm;
import cn.windy.samary.utils.BuildTree;
import cn.windy.samary.utils.Res;
import cn.windy.samary.utils.ResourceBundleUtil;
import cn.windy.samary.utils.ShiroUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zyl
 * @date 2018/5/14 15:51
 */
@Service
public class UserServiceImpl extends AbstractServiceImpl<User> implements IUserService {

    @Resource
    private UserMapper userMapper;
    @Resource
    private IUserRoleService userRoleService;
    @Resource
    private CustomShiroRealm customShiroRealm;
    @Resource
    private UserRoleMapper userRoleMapper;
    @Resource
    private IDeptService deptService;
    @Resource
    private DeptMapper deptMapper;

    @Override
    public List<Tree<Permission>> initMenu(String userId) {
        if (userId != null) {
            Map<String, Object> map = new HashMap<>();
            map.put("permType", Constants.PERM_TYPE_MENU);
            //所有菜单
            List<Permission> am = null;
            //用户角色
            List<String> roleStringList = userMapper.getRoleStringByUserId(userId);
            if (roleStringList.size() != 0) {
                if (!roleStringList.contains(Constants.ROLE_SYSTEM)) {
                    //非管理员,查询角色-->查询菜单,(根据userId查询)
                    map.put("userId", userId);
                }
                am = userMapper.getPermissionByUserId(map);
                map.put("pIdNull", true);
                List<Tree<Permission>> trees = new ArrayList<Tree<Permission>>();
                for (Permission menu : am) {
                    Tree<Permission> tree = new Tree<>();
                    tree.setId(menu.getId());
                    tree.setParentId(menu.getpId());
                    tree.setText(menu.getName());
                    Map<String, Object> attributes = new HashMap<>(16);
                    attributes.put("url", menu.getValue());
                    attributes.put("icon", menu.getIcon());
                    tree.setAttributes(attributes);
                    trees.add(tree);
                }
                List<Tree<Permission>> list = BuildTree.buildList(trees, "0");
                return list;
            }
        }
        return null;
    }

    @Override
    public int save(User user, String roles) {
        String username = user.getUsername();
        String pass = ResourceBundleUtil.getString("system", "DEFAULT_PWD");
        Md5Hash md5Hash = new Md5Hash(pass, username, 10);
        user.setPassword(md5Hash.toString());
        int i = insertSelective(user);
        if (roles != null) {
            String[] roleIds = roles.split(",");
            for (String roleId : roleIds) {
                UserRole userRole = new UserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(roleId);
                userRoleService.insertSelective(userRole);
            }
        }
        return i;
    }

    @Override
    public int update(User user, String roles) {
        int i = updateByPrimaryKeySelective(user);
        UserRole ur = new UserRole();
        ur.setUserId(user.getId());
        //删除原有角色
        userRoleService.delete(ur);
        if (roles != null) {
            String[] roleIds = roles.split(",");
            for (String roleId : roleIds) {
                UserRole userRole = new UserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(roleId);
                userRoleService.insertSelective(userRole);
            }
        }
        //清空缓存
        customShiroRealm.clearCachedAuthorizationInfo();
        return i;
    }

    /**
     * 删除用户同时删除角色关联
     *
     * @param id
     */

    public int deleteById(String id) {
        int i = deleteByPrimaryKey(id);
        Map<String, Object> map = new HashMap<>();
        map.put("userId", id);
        userRoleMapper.deleteBy(map);
        return i;
    }

    /**
     * 删除用户同时删除角色关联
     *
     * @param ids
     */
    @Override
    public int deleteByIds(List<String> ids) {
        if (ids != null && ids.size() != 0) {
            Example example = new Example(User.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andIn("id", ids);
            int i = deleteByExample(example);
            Map<String, Object> map = new HashMap<>();
            map.put("userIds", ids);
            userRoleMapper.deleteBy(map);
            return i;
        }
        return 0;
    }

    @Override
    public int deleteByPrimaryKey(Object o) {
        int i = userMapper.deleteByPrimaryKey(o);
        Example example = new Example(UserRole.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", o);
        userRoleMapper.deleteByExample(example);
        return i;
    }

    @Override
    public int deleteByPrimaryKeys(List<String> primaryKeys) {
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("id", primaryKeys);
        int i = userMapper.deleteByExample(example);
        Example example2 = new Example(UserRole.class);
        Example.Criteria criteria2 = example2.createCriteria();
        criteria2.andIn("userId", primaryKeys);
        userRoleMapper.deleteByExample(example2);
        return i;
    }

    @Override
    public void setRole(String[] userIds, String[] roleIds) {
        if (roleIds == null) {//需要删除所有角色
            for (String userId : userIds) {
                UserRole userRole = new UserRole();
                userRole.setUserId(userId);
                userRoleService.delete(userRole);
            }
        } else {
            for (String roleId : roleIds) {
                for (String userId : userIds) {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(userId);
                    userRole.setRoleId(roleId);
                    userRoleService.insertSelective(userRole);
                }
            }
        }
    }

    @Override
    public String getRoleShownameByUserId(String id) {
        return userMapper.getRoleShownameByUserId(id);
    }

    @Override
    public List<String> getRoleStringByUserId(String id) {
        return userMapper.getRoleStringByUserId(id);
    }

    @Override
    public List<String> getPermissionStringByUserId(String userId) {
        return userMapper.getPermissionStringByUserId(userId);
    }

    @Override
    public int adminResetPwd(User user) {
        User user0 = selectByPrimaryKey(user.getId());
        Md5Hash md5Hash = new Md5Hash(user.getPassword(), user0.getUsername(), 10);
        user.setPassword(md5Hash.toString());
        return updateByPrimaryKeySelective(user);
    }

    @Override
    public Res resetPwd(UserVo userVo) {
        String userId = ShiroUtils.getUserId();
        if (!userId.equals(userVo.getId())) {
            return Res.error("只能更改自己的密码！");
        }
        User user = selectByPrimaryKey(userId);
        Md5Hash md5HashOld = new Md5Hash(userVo.getPwdOld(), user.getUsername(), 10);
        if (!md5HashOld.toString().equals(user.getPassword())) {
            return Res.error("输入的旧密码错误！");
        }
        Md5Hash md5HashNew = new Md5Hash(userVo.getPwdNew(), user.getUsername(), 10);
        user.setPassword(md5HashNew.toString());
        int i = updateByPrimaryKeySelective(user);
//        customShiroRealm.clearCachedAuthenticationInfo();
        return i != 0 ? Res.ok() : Res.error();
    }

    @Override
    public int updatePersonal(User user) {
        return updateByPrimaryKeySelective(user);
    }


    @Override
    public Tree<Dept> getTree() {
        List<Tree<Dept>> trees = new ArrayList<Tree<Dept>>();
        List<Dept> depts = deptService.selectAll();
        String[] pDepts = deptMapper.listPid();
        String[] uDepts = userMapper.listDeptId();
        String[] allDepts = (String[]) ArrayUtils.addAll(pDepts, uDepts);
        for (Dept dept : depts) {
            if (!ArrayUtils.contains(allDepts, dept.getId())) {
                continue;
            }
            Tree<Dept> tree = new Tree<Dept>();
            tree.setId(dept.getId());
            tree.setParentId(dept.getpId());
            tree.setText(dept.getName());
            Map<String, Object> state = new HashMap<>(16);
            state.put("opened", true);
            state.put("mType", "dept");
            tree.setState(state);
            trees.add(tree);
        }
        List<User> users = userMapper.selectAll();
        for (User user : users) {
            Tree<Dept> tree = new Tree<Dept>();
            tree.setId(user.getId());
            tree.setParentId(user.getDeptId());
            tree.setText(user.getNickname());
            Map<String, Object> state = new HashMap<>(16);
            state.put("opened", true);
            state.put("mType", "user");
            tree.setState(state);
            trees.add(tree);
        }
        Tree<Dept> t = BuildTree.build(trees);
        return t;
    }

    @Override
    public List<Role> getRoleByUserId(String userId) {
        return userMapper.getRoleByUserId(userId);
    }

    /**
     * 根据角色值查询用户id
     *
     * @param realname 角色值
     * @return 用户id
     */
    @Override
    public List<String> findUserIdByRealname(String realname) {
        return userMapper.findUserIdByRealname(realname);
    }

    public static void main(String[] args) {
        Md5Hash md5Hash = new Md5Hash("11111", "tttt", 10);
        System.out.println(md5Hash);
    }
}
